/*
 * Copyright (c) 2022. China Mobile (SuZhou) Software Technology Co.,Ltd. All rights reserved.
 * Lakehouse is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

package com.chinamobile.cmss.lakehouse.api.controller;

import com.chinamobile.cmss.lakehouse.api.dto.LakehouseInstanceBean;
import com.chinamobile.cmss.lakehouse.api.exceptions.ApiException;
import com.chinamobile.cmss.lakehouse.api.service.LakehouseInstanceService;
import com.chinamobile.cmss.lakehouse.common.Constants;
import com.chinamobile.cmss.lakehouse.common.enums.Status;
import com.chinamobile.cmss.lakehouse.common.utils.Result;
import com.chinamobile.cmss.lakehouse.dao.entity.UserEntity;

import java.util.Map;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

@Slf4j
@Api(value = "Cluster Administration", protocols = "http")
@RestController
@RequestMapping("/instances")
public class InstanceController extends BaseController {

    @Autowired
    private LakehouseInstanceService lakehouseInstanceService;

    @ApiOperation(value = "createInstance")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId", value = "userId", required = true, dataType = "String",
            dataTypeClass = String.class, paramType = "header")})
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public Result createInstance(@RequestHeader(name = "userId") String userId,
                                 @RequestBody LakehouseInstanceBean lakehouseInstanceBean) {
        Map<String, Object> result = lakehouseInstanceService.createLakehouseInstance(userId, lakehouseInstanceBean);
        return convertToResult(result);
    }

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ApiOperation(value = "instancesList", notes = "get instance list")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId", value = "userId", required = true, dataType = "String",
            dataTypeClass = String.class, paramType = "header")
    })
    @ResponseStatus(HttpStatus.OK)
    @ApiException(Status.LAKEHOUSE_INSTANCE_NAME_LIST_ERROR)
    public Result getInstanceNameList(
        @RequestHeader(value = "userId") String userId,
        @RequestParam(name = "engineType", required = false) String engineType) {
        Map<String, Object> result = lakehouseInstanceService.getInstanceNames(userId, engineType);
        return convertToResult(result);
    }

    @RequestMapping(value = "/list-paging", method = RequestMethod.GET)
    @ApiOperation(value = "instancesListPage", notes = "get instance list page")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", required = true, dataType = "Int", example = "1"),
        @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", required = true, dataType = "Int", example = "10"),
        @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", type = "String")
    })
    @ResponseStatus(HttpStatus.OK)
    @ApiException(Status.LAKEHOUSE_INSTANCE_NAME_LIST_ERROR)
    public Result getInstanceListPage(
        @ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) UserEntity loginUser,
        @RequestParam(value = "searchVal", required = false) String searchVal,
        @RequestParam("pageNo") Integer pageNo,
        @RequestParam("pageSize") Integer pageSize) {
        Result result = checkPageParams(pageNo, pageSize);
        if (!result.checkResult()) {
            return result;

        }
        result = lakehouseInstanceService.getInstanceList(loginUser, searchVal, pageNo, pageSize);
        return result;
    }

    @ApiOperation(value = "releaseInstance")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId", value = "userId", required = true, dataType = "String",
            dataTypeClass = String.class, paramType = "header"),
        @ApiImplicitParam(name = "instance_id", value = "instanceId", required = true, dataType = "String",
            dataTypeClass = String.class, paramType = "path")})
    @RequestMapping(value = "/{instance_id}/release", method = RequestMethod.POST)
    public void release(@RequestHeader(value = "userId") String userId,
                        @PathVariable(name = "instance_id") String instanceId) {
        lakehouseInstanceService.cancelLakehouseInstance(userId, instanceId);
    }

    @ApiOperation(value = "getInstance")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "instance_id", value = "instanceId", required = true, dataType = "String",
            dataTypeClass = String.class, paramType = "path")})
    @RequestMapping(value = "/{instance_id}", method = RequestMethod.GET)
    public Result getInstance(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) UserEntity loginUser,
                              @PathVariable(name = "instance_id") String instanceId) {
        Map<String, Object> result = lakehouseInstanceService.getInstance(loginUser, instanceId);
        return convertToResult(result);
    }

}
